using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using viBook.Common;
using viBook.Filters;
using viBook.Helpers;
using viBook.ModelBinders;
using viBook.Models;
using viBook.Repositories;

namespace viBook.Controllers
{
    public class BooksController : BaseController
    {
        #region Constructors and Repository vars

        private readonly IActivityRepository _activityRepository;
        private readonly IBookRepository _bookRepository;
        private readonly ICategoryRepository _categoryRepository;
        private readonly IContentTagRepository _contentTagRepository;
        private readonly IUserRepository _userRepository;

        public BooksController(
            IBookRepository bookRepository,
            ICategoryRepository categoryRepository,
            IContentTagRepository contentTagRepository,
            IActivityRepository activityRepository,
            IUserRepository userRepository)
        {
            _categoryRepository = categoryRepository;
            _bookRepository = bookRepository;
            _contentTagRepository = contentTagRepository;
            _activityRepository = activityRepository;
            _userRepository = userRepository;
        }

        #endregion

        public ViewResult Details(int id)
        {
            ViewBag.UserBookCollection = _bookRepository.GetUserBookByBookId(id);
            ViewBag.AuthorBookCollection = _bookRepository.GetAuthorBookByBookId(id);
            Book book = _bookRepository.FindWithAddedView(id, ExtendedIdentity.Id);
            ViewBag.IsBookOwner = ExtendedIdentity.Id == book.UploadedBy;
            return View(book);
        }

        [ExtendedAuthentication]
        public ActionResult Create()
        {
            PopuplateCategories();
            return View(new Book());
        }

        [HttpPost, ExtendedAuthentication]
        public ActionResult Create([ModelBinder(typeof(BookBinders))] Book book)
        {
            if (!string.IsNullOrEmpty(book.Title))
            {
                if(
                    _bookRepository.All.Any(
                        b => b.Title.ToLower().Equals(book.Title.ToLower().Trim()) && b.Id != book.Id))
                    ModelState.AddModelError("Title", Constant.BookTitleExistedMessage);

            }
            if (ModelState.IsValid)
            {
                _bookRepository.InsertOrUpdate(book);
                _bookRepository.Save();

                _activityRepository.CreateActivity(book, Constant.CreatedBookType);
                _activityRepository.Save();
                return RedirectToAction("Index", "Account", new { ExtendedIdentity.Id });
            }
            PopuplateCategories();
            return View(new Book());
        }

        [ExtendedAuthentication]
        public ActionResult Edit(int id)
        {
            PopuplateCategories();
            return View(_bookRepository.Find(id));
        }

        [HttpPost, ExtendedAuthentication]
        public ActionResult Edit(Book book)
        {
            if (!string.IsNullOrEmpty(book.Title))
            {
                if (
                    _bookRepository.All.Any(
                        b => b.Title.ToLower().Equals(book.Title.ToLower().Trim()) && b.Id != book.Id))
                    ModelState.AddModelError("Title", Constant.BookTitleExistedMessage);

            }
            if (ModelState.IsValid)
            {
                if (!string.IsNullOrEmpty(Request["filesUploaded"]))
                {
                    if (!string.IsNullOrEmpty(book.CoverUrl))
                        Helpers.Helpers.DeleteFile(book.CoverUrl);
                    book.CoverUrl = Request["filesUploaded"];
                }

                if (!string.IsNullOrEmpty(Request["listSortedChapterId"]))
                    book.ListSortedChapterId = Request["listSortedChapterId"];

                _bookRepository.InsertOrUpdate(book);
                return RedirectToAction("Details", new { id = book.Id });
            }
            PopuplateCategories();
            return View(book);
        }

        [HttpPost]
        [JsonAuthentication]
        public JsonResult DeleteConfirmed(int id)
        {
            _bookRepository.Delete(id);
            _bookRepository.Save();
            _activityRepository.DeleteActivity(id, Constant.CreatedBookType);
            _activityRepository.Save();
            return SuccessFeedback;
        }

        public JsonResult ExistBookTitle(string title, int bookId)
        {
            if (!String.IsNullOrEmpty(title.Trim()))
            {
                IQueryable<Book> books = _bookRepository.All;
                foreach (Book book in books)
                {
                    if (book.Title.Equals(title.Trim()) && book.Id != bookId)
                    {
                        ModelState.AddModelError("Title", Constant.BookTitleExistedMessage);
                        return Json(new
                                        {
                                            Valid = false,
                                            Message = Constant.BookTitleExistedMessage
                                        });
                    }
                }
                return Json(new
                                {
                                    Valid = true
                                });
            }

            ModelState.AddModelError("Title", Constant.BookTitleMissingErrorMessage);
            return Json(new
                            {
                                Valid = false,
                                Message = Constant.BookTitleMissingErrorMessage
                            });
        }

        public ActionResult SearchResult(string searchContent)
        {

            ViewBag.ListMostPopularTags = _contentTagRepository.GetMostPopularTags();
            ViewBag.ListMostPopularUser = _userRepository.GetMostPopularUsers();
            ViewBag.ListMostPopularBook = _bookRepository.GetMostPopularBook();
            if (!string.IsNullOrEmpty(searchContent))
            {
                ViewBag.SearchContent = searchContent.Trim();
                return View(_bookRepository.SearchBook(searchContent.Trim()));
            }
            return View(new List<Book>());
        }


        public string UploadImage(HttpPostedFileBase fileData, FormCollection forms)
        {
            try
            {
                string savedFilename = string.Empty;


                foreach (string file in Request.Files)
                {
                    HttpPostedFileBase postedFileBase = Request.Files[file];

                    if (postedFileBase != null && postedFileBase.ContentLength > 0)
                    {
                        string filename = DateTime.Now.ToString("dd_MM_yyyy_HH_mm_ss") + "_" +
                                          Path.GetFileName(postedFileBase.FileName);


                        savedFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Constant.SaveImagePath,
                                                     filename);
                        if (
                            !Directory.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Constant.SaveImagePath)))
                            Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                                   Constant.SaveImagePath))
                                ;

                        postedFileBase.SaveAs(savedFilename);
                    }
                }

                return savedFilename.Replace(Server.MapPath("~"), "/").Replace("\\", "/");
            }
            catch (Exception e)
            {
                return (e.Message);
            }
        }

        private void PopuplateCategories()
        {
            ViewBag.CategoryCollection = _categoryRepository.All.ToList().Select(category => new SelectListItem
                                                                                                 {
                                                                                                     Selected = false,
                                                                                                     Value = category.Id.ToString(),
                                                                                                     Text = category.CategoryName
                                                                                                 });
        }

        public ActionResult FetchNextCommentPage(int pageNumber)
        {
            List<Book> listBooks = _bookRepository.FetchCommentsByPage(pageNumber).ToList();
            return Json(listBooks.ListBookToJsonResult());
        }

        [OutputCache(Duration = 5, VaryByParam = "q")]
        public string SearchContentTag(string q)
        {
            IEnumerable<string> result = _contentTagRepository.FindContentTags(q, Constant.TakedItem);
            return String.Join(Environment.NewLine, result);
        }

        [ExtendedAuthentication]
        public ActionResult ReportBook(int id)
        {
            DataFeedback feedback = _bookRepository.ReportBook(id, ExtendedIdentity.Id);
            if (feedback.IsSuccess)
                return SuccessFeedback;
            return Json(new { success = false, message = feedback.Message });
        }

        [HttpPost]
        [JsonAuthentication]
        public JsonResult Like(int id)
        {
            DataFeedback feedback = _bookRepository.Like(id, ExtendedIdentity.Id);
            if (feedback.IsSuccess)
            {
                BookLike bookLike = _activityRepository.FindBookLike(id, ExtendedIdentity.Id);
                if (bookLike != null)
                {
                    _activityRepository.CreateActivity(bookLike, Constant.LikedBookType);
                    _activityRepository.Save();
                }

                return SuccessFeedback;
            }
            return Json(new { success = false, message = feedback.Message });
        }

        [HttpPost]
        [JsonAuthentication]
        public JsonResult UnLike(int id)
        {
            DataFeedback feedback = _bookRepository.Like(id, ExtendedIdentity.Id);
            if (!feedback.IsSuccess)
            {
                BookLike bookLike = _activityRepository.FindBookLike(id, ExtendedIdentity.Id);
                if (bookLike != null)
                {
                    _activityRepository.DeleteActivity(bookLike.Id, Constant.LikedBookType);
                    _activityRepository.Save();
                }

                return SuccessFeedback;
            }
            return Json(new { success = false, message = feedback.Message });
        }
    }
}